import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
import { ElMessage } from 'element-plus';

class WebSocketManager {
    constructor() {
        this.serverHost = 'localhost';
        this.serverPort = 50407;
        this.endpoint = `http://${this.serverHost}:${this.serverPort}/ws`;
        this.stompClient = null;
        this.socket = null;
        this.connectCallback = null; // 连接成功回调
        this.reconnectTimer = null; // 重连定时器
        this.reconnectDelay = 5000; // 初始重连间隔（5秒）
        this.maxReconnectDelay = 30000; // 最大重连间隔（30秒）
        this.subscriptions = new Map(); // 存储已订阅的频道和回调：{ topic: { callback, subscription } }
    }
    // 设置连接成功回调
    setConnectCallback(callback) {
        this.connectCallback = callback;
    }

    // 核心连接方法（支持自动重连，新增 onConnected 回调参数）
    connect() {  // 新增可选回调参数
        if (this.stompClient?.connected) {
            console.log('WebSocket已连接，无需重复连接');
            return;
        }

        this.socket = new SockJS(this.endpoint);
        this.stompClient = Stomp.over(this.socket);

        // 心跳配置
        this.stompClient.heartbeat.outgoing = 10000;
        this.stompClient.heartbeat.incoming = 0;

        // 连接成功回调
        this.stompClient.connect(
            {},
            () => {
                console.log('WebSocket连接成功');
                this.reconnectDelay = 5000; // 连接成功后重置重连间隔
                this.reconnectTimer && clearTimeout(this.reconnectTimer); // 清除重连定时器
                this.resubscribeAll(); // 重新订阅所有频道（解决重连后订阅丢失问题）

                // 新增：执行用户自定义的连接成功回调
                if (typeof this.connectCallback === 'function') {
                    this.connectCallback();
                }
            },
            (err) => {
                console.error('WebSocket连接失败:', err);
                ElMessage.error('WebSocket连接异常，尝试重连...');
                this.scheduleReconnect(); // 连接失败时触发重连
            }
        );
    }

    // 自动重连调度（指数退避策略）
    scheduleReconnect() {
        if (this.reconnectTimer) return;

        this.reconnectTimer = setTimeout(() => {
            this.reconnectTimer = null;
            this.connect();
            this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay); // 重连间隔逐渐增加
        }, this.reconnectDelay);
    }

    // 订阅频道（支持重连后自动恢复）
    subscribe(topic, callback) {
        if (!this.stompClient || !this.stompClient.connected) {
            console.warn('WebSocket未连接，订阅将在连接后自动执行');
            // 未连接时暂存订阅，连接成功后自动触发
            this.subscriptions.set(topic, { callback, pending: true });
            return;
        }

        const subscription = this.stompClient.subscribe(topic, (message) => {
            callback(JSON.parse(message.body));
        });
        this.subscriptions.set(topic, { callback, subscription });
    }

    // 取消订阅
    unsubscribe(topic) {
        const sub = this.subscriptions.get(topic);
        if (sub?.subscription) {
            sub.subscription.unsubscribe();
            this.subscriptions.delete(topic);
        }
    }

    // 重连后重新订阅所有频道
    resubscribeAll() {
        this.subscriptions.forEach(({ callback }, topic) => {
            this.subscribe(topic, callback); // 重新执行订阅逻辑
        });
    }

    // 断开连接（手动调用）
    disconnect() {
        if (this.stompClient) {
            this.stompClient.disconnect();
            this.stompClient = null;
        }
        if (this.socket) {
            this.socket.close();
            this.socket = null;
        }
        this.reconnectTimer && clearTimeout(this.reconnectTimer);
        this.subscriptions.clear(); // 断开时清空订阅
    }
}

// 导出单例实例（全局唯一）
export default new WebSocketManager();
